﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the GNU General Public License version 2 (GPLv2).
// See accompanying file License.txt or copy at http://phuse.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Phuse.Net.Forums
{
    using System;
    using System.Data.Linq;
    using System.Data.Linq.Mapping;
    using System.Diagnostics.CodeAnalysis;
    using Microsoft.Phone.Data.Linq.Mapping;

    /// <content>Contains the LINQ to SQL portion of the <see cref="Group"/> class.</content>
    [Table]
    [Index(Columns = "HostId,Name", IsUnique = true)]
    [SuppressMessage("Microsoft.StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "The order of the properties defines the order of database columns.")]
    internal sealed partial class Group
    {
        private string displayName;
        private int newInboundArticlesReceiveLimit = 500;
        private int cachedInboundArticlesLimit = 2000;

        private EntityRef<Host> hostRef;

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        [Column(IsPrimaryKey = true, IsDbGenerated = true)]
        internal int Id { get; private set; }

        [Column(UpdateCheck = UpdateCheck.Never)]
        private int HostId { get; set; }

        /// <summary>See <see cref="IGroup.Name"/>.</summary>
        [Column(CanBeNull = false, DbType = "NVARCHAR(254) NOT NULL", UpdateCheck = UpdateCheck.Never)]
        public string Name { get; internal set; }

        /// <summary>See <see cref="IGroup.DisplayName"/>.</summary>
        [Column(Storage = "displayName", CanBeNull = false, DbType = "NVARCHAR(32) NOT NULL", UpdateCheck = UpdateCheck.Never)]
        public string DisplayName
        {
            get
            {
                return this.displayName;
            }

            set
            {
                this.AssertValid();
                this.displayName = value;
            }
        }

        /// <summary>See <see cref="IGroup.NewInboundArticlesReceiveLimit"/>.</summary>
        [Column(Storage = "newInboundArticlesReceiveLimit", UpdateCheck = UpdateCheck.Never)]
        public int NewInboundArticlesReceiveLimit
        {
            get
            {
                return this.newInboundArticlesReceiveLimit;
            }

            set
            {
                this.AssertValid();

                if (value <= 0)
                {
                    throw new ArgumentOutOfRangeException("value", "Positive number required.");
                }

                this.newInboundArticlesReceiveLimit = value;
            }
        }

        /// <summary>See <see cref="IGroup.CachedInboundArticlesLimit"/>.</summary>
        [Column(Storage = "cachedInboundArticlesLimit", UpdateCheck = UpdateCheck.Never)]
        public int CachedInboundArticlesLimit
        {
            get
            {
                return this.cachedInboundArticlesLimit;
            }

            internal set
            {
                this.AssertValid();

                if (value <= 0)
                {
                    throw new ArgumentOutOfRangeException("value", "Positive number required.");
                }

                this.cachedInboundArticlesLimit = value;
            }
        }

        [Column(UpdateCheck = UpdateCheck.Never)]
        internal int? SelectedInboundArticleId { get; set; }

        [Column(UpdateCheck = UpdateCheck.Never)]
        private bool? IsOriginalInboundArticleBeingWatchedFilter { get; set; }

        [Column(UpdateCheck = UpdateCheck.Never)]
        private bool? HasOriginalInboundArticleBeenReadFilter { get; set; }

        [Column(UpdateCheck = UpdateCheck.Never)]
        private bool? IsFollowupInboundArticleBeingWatchedFilter { get; set; }

        [Column(UpdateCheck = UpdateCheck.Never)]
        private bool? HasFollowupInboundArticleBeenReadFilter { get; set; }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        [Association(Name = "Host_Group", Storage = "hostRef", ThisKey = "HostId", IsForeignKey = true)]
        internal Host Host
        {
            get { return this.hostRef.Entity; }
            set { this.hostRef.Entity = value; }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private void OnValidate(ChangeAction action)
        {
            if (action == ChangeAction.Delete)
            {
                this.Root.AssertSendReceiveNotInProgress();
            }
        }
    }
}
